package main

import (
	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
	mybot "lidongyooo/search-bot/bot"
	"lidongyooo/search-bot/models"
	"lidongyooo/search-bot/pkg/config"
	"lidongyooo/search-bot/pkg/db"
	"log"
	"strconv"
	"strings"
	"sync"
	"time"
)

var (
	Bot             *mybot.MyBot
	startSearch     string   = config.Viper.GetString("MESSAGE.SEARCH")
	lastInsertTimes sync.Map = sync.Map{}
	delayMessages   sync.Map = sync.Map{}
)

func main() {
	log.SetFlags(log.Lshortfile)
	db.ConnectDB()

	Bot, _ = mybot.New(config.Viper.GetString("TOKEN"))
	Bot.Debug = config.Viper.GetBool("APP.DEBUG")

	updateConfig := tgbotapi.NewUpdate(0)
	updateConfig.Timeout = 30
	updates := Bot.GetUpdatesChan(updateConfig)

	for update := range updates {

		if update.MyChatMember != nil && update.MyChatMember.NewChatMember.IsAdministrator() {

			go administrator(update.MyChatMember)
		} else if update.Message != nil {

			myMessage := &mybot.MyMessage{Message: update.Message}
			if myMessage.Chat.IsPrivate() {
				if myMessage.IsCommand() {
					go command(myMessage)
				} else if myMessage.Document != nil {
					go mybot.FileHandler(myMessage)
				}
			} else if myMessage.Chat.IsSuperGroup() || myMessage.Chat.IsGroup() || myMessage.Chat.IsChannel() {
				go group(myMessage)
			}
		}

	}
}

func administrator(member *tgbotapi.ChatMemberUpdated) {
	originChatId := models.GetOriginChatId(int(member.Chat.ID))
	db.MessageTableCreate(mybot.GetMessageTableName(originChatId))
	chatModel := models.Chat{
		ChatId: models.GetOriginChatId(int(member.Chat.ID)),
		Name:   member.Chat.Title,
		Type:   member.Chat.Type,
		Status: 2,
	}
	db.MySQL.Create(&chatModel)
	Bot.SendMessage(member.Chat.ID, "搜索功能已开启，使用: '"+startSearch+": 关键字'")
}

func gotSearch(text string) (got bool, keyword string) {
	textLower := strings.ToLower(text)
	searches := []string{": ", ":", "： ", "："}
	for _, search := range searches {
		if strings.HasPrefix(textLower, startSearch+search) {
			got = true
			keyword = text[len(startSearch+search):]
			break
		}
	}

	return got, keyword
}

func insertMessages(tableName string) []models.Message {
	var (
		lastTime      time.Time
		messagesModel []models.Message
	)

	if val, ok := delayMessages.Load(tableName); ok {
		messagesModel, _ = val.([]models.Message)
	} else {
		delayMessages.Store(tableName, messagesModel)
	}
	if val, ok := lastInsertTimes.Load(tableName); ok {
		lastTime, _ = val.(time.Time)
	} else {
		lastTime = time.Now()
		lastInsertTimes.Store(tableName, lastTime)
	}

	if (time.Now().Unix()-lastTime.Unix() >= 60 && len(messagesModel) > 0) || len(messagesModel) >= 60 {
		db.MySQL.Table(tableName).Create(&messagesModel)
		messagesModel = nil
		delayMessages.Store(tableName, nil)
		lastInsertTimes.Store(tableName, time.Now())
	}

	return messagesModel
}

func group(ms *mybot.MyMessage) {
	chatId := models.GetOriginChatId(int(ms.Chat.ID))
	tableName := mybot.GetMessageTableName(chatId)
	messagesModel := insertMessages(tableName)

	if ok, keyword := gotSearch(ms.Text); ok {
		if len([]rune(keyword)) < 2 {
			Bot.SendReplyMessage(ms.Chat.ID, ms.MessageID, "至少输入两个字符")
		} else {
			ms.Search(keyword)
		}
	} else if ms.Text != "" && len(ms.Text) > 1 {
		messageModel := models.Message{
			MessageId: ms.MessageID,
			Username:  ms.From.UserName,
			Text:      mybot.TextFormat(ms.Text),
			FromName:  ms.From.FirstName + " " + ms.From.LastName,
			FromId:    "user" + strconv.Itoa(int(ms.From.ID)),
			SentAt:    models.LocalTime{Time: time.Unix(int64(ms.Date), 0).Local()},
			ChatId:    chatId,
		}

		delayMessages.Store(tableName, append(messagesModel, messageModel))
	}
}

func command(ms *mybot.MyMessage) {
	switch ms.Command() {
	case "start":
		introduce(ms)
	case "search":
		searchKeyboard := tgbotapi.NewInlineKeyboardMarkup(
			tgbotapi.NewInlineKeyboardRow(
				tgbotapi.NewInlineKeyboardButtonURL("邀请我", "http://t.me/"+mybot.Me.UserName+"?startgroup=botstart"),
			),
		)
		msg := tgbotapi.NewMessage(ms.Chat.ID, "将当前机器人加入到需要增加搜索功能的群组，并给予管理员席位(无需任何权限)\n\n如果需要添加历史聊天记录，将从桌面端导出的 JSON 聊天记录文件上传\n\n注：聊天记录每分钟更新一次，所以搜索会有一分钟的延迟")
		msg.ReplyMarkup = searchKeyboard
		Bot.Send(msg)
	}
}

func introduce(ms *mybot.MyMessage) {
	Bot.SendMessage(ms.Chat.ID, "/search 为你的群组加上搜索功能")
}
